﻿using Acrobat;
using Microsoft.VisualBasic.Devices;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using AFORMAUTLib;
using Word = Microsoft.Office.Interop.Word;
namespace GetWordInfo
{
    public struct ActicleInfo
    {
        public string filename;   //word文件名
        public long id;           //id
        public int pageNum;       //页数
        public int wordCount;     //字数
        public string paperCode;  //证券代码
        public string paperName;  //证券简称
        public string paperNumber;//证券编号
        public int tableWordNum;      //表格数量
        public int pictureNum;    //表格数量
        public int rowNum;        //表格行数
        public string property;   //公告属性  董事会 、监事会、股东大会
        public string priviewUrl; //word生成的url，方便定稿使用
        public void init()
        {
            filename = "";
            id = 0;
            pageNum = 0;
            wordCount = 0;
            paperCode = "";
            paperName = "";
            paperNumber = "";
            tableWordNum = 0;
            pictureNum = 0;
            rowNum = 0;
            property = "";
            priviewUrl = "";
        }

    }







    public class ReadWord
    {
        Microsoft.Office.Interop.Word.Application app = null;
        string fileName;
        Word.Document curdoc;
        object unknow = Type.Missing;
        object oMissing = System.Reflection.Missing.Value;

        private string ActicleProperty;
        public ActicleInfo info;
        #region 错误编码
        public const int SuccessWord = 1;
        public const int ErrorFileNotFound = 2;
        public const int ErrorFileLoad = 3;
        public const int ErrorApplication = 4;
        public const int ErrorFileSuffix = 5;
        public const int ErrorOther = 9;
        #endregion
        
        /// <summary>
        /// 根据文件名来获取公告相关信息
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public int getWordInfoByName(string filepath,string property)
        {
            string result = "";
            int state = 0;
            fileName = filepath;
            ActicleProperty = property;

            try
            {
                state = openWordByName(filepath);
                info.init();
                if (state == 1)    //意味着打开成功
                {
                    state = beginRead();
                }
            }
            catch(Exception ex)
            {

            }
            return state;
        }

        private int openWordByName(string filepath)
        {
            int state = -1;
            app = new Word.Application();
            bool readOnly = false;
            try
            {
                app.Options.CheckGrammarWithSpelling = false;        //关掉语法检查
                app.Options.SuggestSpellingCorrections = false;
                app.Options.AllowOpenInDraftView = true;
                app.Options.DoNotPromptForConvert = false;

                app.Visible = true;
                object file = filepath;
                object isread = readOnly;
                curdoc = app.Documents.Open(ref file,
                    ref unknow, ref isread, ref unknow, ref unknow,
                    ref unknow, ref unknow, ref unknow, ref unknow,
                    ref unknow, ref unknow, ref unknow, ref unknow,
                    ref unknow, ref unknow, ref unknow);    //用只读方式打开word
                state = 1;
            }
            catch (FileNotFoundException ex)
            {
                //文件没有找到
                state = ErrorFileNotFound;

            }
            catch (FileLoadException ex)
            {
                //加载文件失败
                state = ErrorFileLoad;
                writeLog(fileName, ex.Message);
            }
            catch (ApplicationException ex)
            {
                //应用程序失败
                state = ErrorApplication;
                writeLog(fileName, ex.Message);

            }
            catch (COMException e3)
            {
                if (e3.Message.Contains("文件扩展名不匹配"))
                    state = ErrorFileSuffix;
                else
                    state = ErrorOther;

                writeLog(fileName, e3.Message);
            }
            catch (Exception ex)
            {
                //其它未知错误
                state = ErrorOther;
                writeLog(fileName, ex.Message);
            }
            return state;
        }







        private string word2jpg()
        {
            string url = "";
            string filepath = "";
            string pdfpath = "";   //pdf文件路径
            string jpgpath = "";
            try
            {
               
                CAcroPDDoc pdfDoc;
                Acrobat.CAcroPDPage pdfPage;
                Acrobat.CAcroRect pdfRect;
                Acrobat.CAcroPoint pdfPoint;

                int index = fileName.LastIndexOf("\\");
                string name = fileName.Substring(index + 1);
                filepath = fileName.Substring(0, index);
                filepath += "\\img";
                if (!Directory.Exists(filepath))
                    Directory.CreateDirectory(filepath);
                index = name.LastIndexOf('.');
                name = name.Substring(0, index + 1) + "pdf";
                pdfpath = filepath + "\\" + name;
                try
                {
                    curdoc.ExportAsFixedFormat(pdfpath, Word.WdExportFormat.wdExportFormatPDF);
                    CloseWord();
                }
                catch(Exception ex)
                {
                    CloseWord();
                    return "";
                }

                try
                {
                    
                    jpgpath = filepath + "\\temp";
                    string templatePortraitFile = Application.StartupPath + @"\pdftemplate_portrait.gif";
                    string templateLandscapeFile = Application.StartupPath + @"\pdftemplate_portrait.gif"; ;
                    Clipboard.Clear();
                    //     AcroPDDoc pdfd = new AcroPDDoc();
                    pdfDoc =(Acrobat.CAcroPDDoc)Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.PDDoc", "");
                    //    pdfDoc = new AcroPDDoc();
                    bool ret = pdfDoc.Open(pdfpath);
                    if (!ret)
                        return "";
                    int pageCount = pdfDoc.GetNumPages();

                    // Get the first page
                    pdfPage = (Acrobat.CAcroPDPage)pdfDoc.AcquirePage(0);
                    pdfPoint = (Acrobat.CAcroPoint)pdfPage.GetSize();
                    pdfRect = (Acrobat.CAcroRect)Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.Rect", "");
                    pdfRect.Left = 0;
                    pdfRect.right = pdfPoint.x;
                    pdfRect.Top = 0;
                    pdfRect.bottom = pdfPoint.y;
                    int resolution = 1;
                    pdfPage.CopyToClipboard(pdfRect, 0, 0, 100);
                    for (int i = 1; i <= pageCount; i++)
                    {
                        pdfPage = (Acrobat.CAcroPDPage)pdfDoc.AcquirePage(i - 1);
                        pdfPoint = (Acrobat.CAcroPoint)pdfPage.GetSize();
                        pdfRect = (Acrobat.CAcroRect)Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.Rect", "");
                        int imgWidth = (int)((double)pdfPoint.x * resolution);
                        int imgHeight = (int)((double)pdfPoint.y * resolution);
                        pdfRect.Left = 0;
                        pdfRect.right = (short)imgWidth;
                        pdfRect.Top = 0;
                        pdfRect.bottom = (short)imgHeight;
                        pdfPage.CopyToClipboard(pdfRect, 0, 0, (short)(100 * resolution));

                        IDataObject clipboardData1 = Clipboard.GetDataObject();
                        jpgpath = filepath + "\\temp_" + i.ToString() + ".jpg";
                        if (clipboardData1.GetDataPresent(DataFormats.Bitmap))
                        {
                            Bitmap pdfBitmap = (Bitmap)clipboardData1.GetData(DataFormats.Bitmap);
                            pdfBitmap.Save(jpgpath, ImageFormat.Jpeg);
                            pdfBitmap.Dispose();

                        }
                    }

                    pdfDoc.Close();
                    Marshal.ReleaseComObject(pdfPage);
                    Marshal.ReleaseComObject(pdfRect);
                    Marshal.ReleaseComObject(pdfDoc);
                    
                    return filepath;

                }
                catch (Exception ex)
                {


                }
                return jpgpath;


                object What = Word.WdGoToItem.wdGoToPage;
                object Which = Word.WdGoToDirection.wdGoToFirst;
                int pageNum = getPageNumber();       //获取word页数
                for(int i=1;i<pageNum+1;i++)
                {
                    object startIndex = i.ToString();
                    jpgpath = filepath + "\\temp_" + i.ToString() + ".jpg";
                    curdoc.ActiveWindow.Selection.GoTo(ref What, ref Which, ref unknow, ref startIndex); // 转到下一页
                    try
                    {
                        Clipboard.Clear();
                        Word.Range range = curdoc.ActiveWindow.Selection.Paragraphs[1].Range;
                        Word.Range endrange = range.GoToNext(Word.WdGoToItem.wdGoToPage);
                        Word.Range temprange = curdoc.Range(range.Start, endrange.Start);
                        temprange.Select();
                        app.Selection.CopyAsPicture();
                        object dataType = Word.WdPasteDataType.wdPasteMetafilePicture;
                        if (Clipboard.GetDataObject() != null)
                        {
                            IDataObject data = Clipboard.GetDataObject();
                            object o = data.GetData("MetaFilePict");
                            Bitmap bmp = null;
                            System.IO.MemoryStream ms = o as System.IO.MemoryStream;
                            if(ms != null)
                            {
                                Image img = Image.FromStream(ms);
                                img.Save(jpgpath, System.Drawing.Imaging.ImageFormat.Jpeg);
                            }
                         
                        }
                        else
                        {
                            continue;
                        }
                    }
                    catch(Exception ex)
                    {
                        continue;
                    }
                }


            }
            catch(Exception ex)
            {
                writeLog(fileName,"url转换失败:" + ex.ToString());
            }

            return filepath;
        }


        private  int beginRead()
        {
            try
            {
                info.pageNum = getPageNumber();   //得到文档总页数
                info.wordCount = getWordCount();  //文档字数统计
                getTableInfo();
                getPictureNum();
                readWordContent();
                info.priviewUrl = word2jpg();
            }
            catch(Exception ex)
            {
                writeLog(fileName, ex.ToString());
                return 0;
               
            }
            return 1;
        }




        public void CloseWord()
        {
            object SaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges;
            try
            {
                if (curdoc != null)
                    curdoc.Close(ref SaveChanges, ref unknow, ref unknow);

            }
            catch (Exception e)
            {

            }
            try
            {
                if (app != null)
                    app.Quit(ref SaveChanges, ref unknow, ref unknow);

            }
            catch (Exception e)
            {

            }
        }


        private void getPictureNum()
        {
            try
            {
                info.pictureNum = curdoc.InlineShapes.Count;
            }
            catch(Exception ex)
            {
                info.pictureNum = 0;
            }
            
        }



        private bool getTableInfo()
        {
            bool success = false;
            int rows = 0;
            try
            {
                int tableNum = curdoc.Tables.Count;
                StringBuilder builder = new StringBuilder();
                string content = "";
                for(int i=1;i<= tableNum;i++)
                {
                    rows += curdoc.Tables[i].Rows.Count;
                    content = curdoc.Tables[i].Range.Text;
                    builder.Append(content);
                }
                content = builder.ToString();
                content = repalceContent(content);
                content = content.Replace("\r\a", "");
                info.tableWordNum = content.Length;
                info.rowNum = rows;
            }
            catch(Exception ex)
            {
                writeLog(fileName, "表格："+ex.Message);
            }

            return success;
        }


        /// <summary>
        /// 读取word内容，获取基本信息
        /// </summary>
        /// <returns></returns>
        private void readWordContent()
        {
            string content = "";
            string headText = "";
            string property = "";
            string[] temp = null;
            bool hasproperty = false;
            bool isjijin = false;                          //是否基金公告
            try
            {
                property = ActicleProperty;
                if (!property.Equals(""))
                    temp = property.Split('_');
                foreach (Word.Section wordSection in curdoc.Sections)
                {
                    Word.Range header = wordSection.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
                    headText = header.Text;
                    headText = repalceContent(headText);
                    headText = headText.Replace("\r", "");  //提取页眉内容.
                    if (!headText.Contains("证券代码") && !headText.Contains("证券简称") && !headText.Contains("公告编号"))
                    {
                        if (headText.Contains("基金"))
                            isjijin = true;
                        headText = "";
                    }
                    break;
                }
                if (!headText.Equals(""))    //意味着有证券代码
                    getCodeInfo(headText,false);
                int paraNum = 1;
                int picNum = curdoc.InlineShapes.Count;        //图片数量
                Word.Range range = null;
                StringBuilder builder = new StringBuilder();
                StringBuilder codeBuilder = new StringBuilder();
                foreach (Word.Paragraph paragraph in curdoc.Paragraphs)
                {
                    range = paragraph.Range;
                    string text = range.Text;
                    text = repalceContent(text);
                    builder.Append(text);
                    if(headText.Equals(""))
                    {
                        if (!isjijin && paraNum < 20)       //默认前10行出现基金两个字就为基金公告
                        {
                            if (text.Contains("基金"))
                                isjijin = true;
                        }
                        if(text.Contains("证券代码") ||text.Contains("证券简称") ||text.Contains("公告编号"))
                        {
                            codeBuilder.Append(text);
                        }
                        if (isjijin && (text.Contains("基金简称") || text.Contains("基金代码")))   //获取基金简称和基金代码
                        {
                            codeBuilder.Append(text);
                            if(text.Contains("基金代码"))
                            {
                                text = codeBuilder.ToString();
                                text = text.Replace("\r", "");
                                getCodeInfo(text, true);
                                break;
                            }
                            
                        }
                        if (!isjijin && paraNum > 20)   //不是基金，同时段落数大于20，则不进行读取
                        {
                            text = codeBuilder.ToString();
                            text = text.Replace("\r", "");
                            getCodeInfo(text, false);
                            break;
                        }
                    }
                    if (!hasproperty)
                    {
                        if (paraNum < 20)
                        {
                            if (temp != null)
                            {
                                text = builder.ToString();
                                for (int i = 0; i < temp.Length; i++)
                                {
                                    if (text.Contains(temp[i]))
                                    {
                                        info.property = temp[i];
                                        hasproperty = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    paraNum++;
                }
            }
            catch(Exception ex)
            {
                writeLog(fileName, ex.Message);
            }
            return ;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="content"></param>
        /// <param name="jijin">是否为基金，否的话即为证券代码或者其他类型</param>
        private void getCodeInfo(string content,bool jijin)
        {
            string[] temp = null;   //为基金分割做准备
            string code = "";       //证券代码
            string name = "";       //证券简称
            string strnumber = "";  //公告编号
            content = content.Replace("\t", "");
            try
            {
                if(!jijin)          //不是基金
                {
                    if(!content.Equals(""))                 //不为空，意味着包含这些信息
                    {
                        int index1 = content.IndexOf("证券代码");
                        int index2 = content.IndexOf("证券简称");
                        code = content.Substring(index1 + 5, index2-5);
                        
                        int index3 = content.IndexOf("公告编号");
                        name = content.Substring(index2 + 5, index3-index2-5);
                        strnumber = content.Substring(index3 + 5);
                    }
                    info.paperCode = code;
                    info.paperName = name;
                    info.paperNumber = strnumber;
                    return;
                }
                //是基金的处理







            }
            catch(Exception ex)
            {

            }
        }



        /************************************************************************/
        /* content 要替换的内容，处理特殊符号，保证比对的误报率降低
        /************************************************************************/
        private string repalceContent(string content)
        {
            string strcontent = content;
            int index = content.IndexOf(')');
            try
            {
                char[] str = strcontent.ToCharArray();
                for (int i = 0; i < str.Length; i++)
                {
                    if (str[i] == 1)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 8194)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 9322)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 21 && i != 0)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 160)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 61472)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 12288)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 32)  //替代
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 31)  //替代
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 14)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 61692)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 61656)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 61618)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 61620)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 40)
                    {
                        str[i] = ' ';
                    }
                    else if (str[i] == 127)
                    {
                        str[i] = ' ';
                    }

                }
                strcontent = new string(str);
                strcontent = strcontent.Replace(" ", "");
                strcontent = strcontent.Replace("\f", "");
                strcontent = strcontent.Replace("\v", "");
                if (strcontent.EndsWith("/\r"))
                {
                    strcontent = strcontent.Replace("/\r", "\r");
                }
               
            }
            catch (System.Exception ex)
            {
                return strcontent;
            }
            return strcontent;

        }


        /// <summary>
        /// 获取word字符数
        /// </summary>
        /// <returns></returns>
        private int getWordCount()
        {
            int wordcount = 0;
            try
            {
                Word.Dialog wdlg = app.Dialogs[Word.WdWordDialog.wdDialogToolsWordCount];
                wdlg.Execute();

                System.Type dlgType = typeof(Word.Dialog);

                // 字符数（计空格）
                object oo = dlgType.InvokeMember("CharactersIncludingSpaces",
                System.Reflection.BindingFlags.GetProperty |
                    System.Reflection.BindingFlags.Public |
                    System.Reflection.BindingFlags.Instance,
                null,
                wdlg,
                null);
                wordcount = Convert.ToInt32(oo.ToString().Replace(",", ""));
              
            }
            catch (System.Exception ex)
            {
                writeLog(fileName, "字数："+ex.ToString());
            }
            return wordcount;
        }

        private int getPageNumber()
        {
            int pageCount = 0;
            Word.WdStatistic stat = Word.WdStatistic.wdStatisticPages;
            try
            {
                pageCount = curdoc.ComputeStatistics(stat, ref oMissing);          //文档页数
            }
            catch (System.Exception ex)
            {
                writeLog(fileName, "页数："+ex.ToString());
                return 0;
            }

            return pageCount;
        }

        /************************************************************************/
        /*function: 错误日志文件,将错误日志记录下来
         *fileName：文件名
         *message： 错误日志信息
        /************************************************************************/
        public void writeLog(string fileName, string message)
        {
            string workPath = System.AppDomain.CurrentDomain.BaseDirectory;  //获取工作路径
            string logPath = workPath + "log";
            string time = DateTime.Now.ToString("yyyy-MM-dd");
            string logFile = logPath + "\\Merge-" + time + ".log";
            string msg = "";
            try
            {
                if (!Directory.Exists(logPath))
                {
                    Directory.CreateDirectory(logPath);
                }
                FileStream fs;
                StreamWriter sw;
                if (File.Exists(logFile))  //验证文件是否存在，有则追加，无则创建
                {
                    fs = new FileStream(logFile, FileMode.Append, FileAccess.Write);
                }
                else
                {
                    fs = new FileStream(logFile, FileMode.Create, FileAccess.Write);
                }
                sw = new StreamWriter(fs);
                msg = fileName + ": " + message + "-----" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n";
                sw.WriteLine(msg);
                sw.Close();
                fs.Close();
            }
            catch (System.Exception ex)
            {
                return;
            }


        }

    }
}
